<?php
/**
 * Service_Mail
 *
 * Класс Service_Mail осуществляет работу c эл. полчтой
 *
 * @author Егоров Александр <slamer@slamer.ru>
 * @author Дмитрий Кузьма <kouzma.d@gmail.com>
 * @version 1.0
 */

class Service_Mail {

  private $subject; // Тема
  private $message; // Сообщение
  private $to;  // Получатель (например, Дмитрий Кузьма)
  private $cc;  // Эл. почта получателя
  private $bcc; // Копия письма
  private $replyTo; // Эл. почта отправителя
  private $attachment = array();  // Вложения
  /**
   * Конструктор
   *
   * @param string $subject - тема
   * @param string $message - сообщение
   * @param mixed $toList - имя получателя (например, Дмитрий Кузьма)
   * @param mixed $ccList - эл. почта
   * @param mixed $bccList - копия письма
   * @param string $replyTo - эл. почта отправителя
   */
  function __construct($subject, $message, $toList, $ccList = 0, $bccList = 0, $replyTo = 0) {
    $this->replyTo = $replyTo;
    $this->subject = $subject;
    $this->message = $message;

    // set the To: recipient(s)
    if ( is_array($toList) ) $this->to = join(",", $toList);
    else $this->to = $toList;

    // set the Cc: recipient(s)
    if (is_array($ccList) && sizeof($ccList)) $this->cc = join( $ccList, "," );
    elseif ( $ccList ) $this->cc = $ccList;

    // set the Bcc: recipient(s)
    if (is_array($bccList) && sizeof($bccList)) $this->bcc = join( $bccList, "," );
    elseif ( $bccList ) $this->bcc = $bccList;

  }

  /**
   * Метод отправляет сообщения по указанным адресам эл. почты
   *
   * @return unknown
   */
  function send() {
    //Создаем заголовки письма
    $this->headers = "From: " . EMAIL_FROM . "\n";
    $this->headers .= 'MIME-Version: 1.0' . "\n";
    $this->headers .= 'Content-Type: text/html; charset=utf-8' . "\n";
    $this->headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
    //Задаем адрес, по которому ожидаем ответ
    if ( $this->replyTo ) $this->headers .= "Reply-To: " . $this->replyTo . "\n";
    // Задаем получателей
    if ( $this->cc ) $this->headers .= "Cc: " . $this->cc . "\n";
    // Задаем скрытые копии
    if ( $this->bcc ) $this->headers .= "Bcc: " . $this->bcc . "\n";
    
    // Сохраняем сообщение на всякий случай
      $strToFile = "<html>";
      $strToFile .= '<meta charset="utf-8" />';
      $strToFile .= "<h2>ЗАГОЛОВКИ:</h2>";
      $strToFile .= $this->headers;
      $strToFile .= "<br />=============";
      $strToFile .= "<h2>КОМУ:</h2>";
      $strToFile .= $this->to;
      $strToFile .= "<br />=============";
      $strToFile .= "<h2>ТЕМА:</h2>";
      $strToFile .= $this->subject;
      $strToFile .= "<br />=============";
      $strToFile .= "<h2>СООБЩЕНИЕ:</h2>";
      $strToFile .= $this->message;
      $strToFile .= "<br />=============<br /></html>";
      $f = fopen(ABSPATH . 'content/mail/' . date("Y_m_d__H_i_s") . '.htm', 'w');
      fwrite($f, $strToFile);
      fclose($f);    
    
    //Отправляем сообщение
    // Если отправка идет на почту
    if ( ! defined( 'MAIL_CLASS_DEFINED' ) ) {
	    return mail ( $this->to, $this->subject, $this->message, $this->headers );
    }
    else { // Если отправка идет в файл

    }
  }

  /**
   * Метод проверяет, корректно ли введен адрес электроноой почты
   *
   * @param string $strEMail - e-mail
   * @return bool
   */
  public static function isEMailCorrect($strEMail) {
    return preg_match("/^[\.\-_A-Za-z0-9]+?@[\.\-A-Za-z0-9]+?\.[A-Za-z0-9]{2,6}$/", $strEMail);
  }
  
  /**
   * Получает данные о письме
   * 
   * @param string $fileFullPath
   */
  public static function getMailInfoFromFile($fileFullPath) {
  	Service_Debug::setDebug();
  	//if (!is_file($fileFullPath)) return null;
  	$handle = fopen($fileFullPath, "r");
  	if (!$handle) return null;
		$fileContent = fread($handle, filesize($fileFullPath));
		fclose($handle);
		return self::getMailInfoFromStr($fileContent);
  }
  
    /**
   * Получает данные о письме
   * 
   * @param string $mailStr
   */
  public static function getMailInfoFromStr($mailStr) {
  	$arrBlocks = preg_split("/\n\n/", $mailStr, 2);
  	if (!isset($arrBlocks[1])) return null;
  	list($metas, $content) = $arrBlocks;
  	$arrMultyparts = array('multipart/mixed', 'multipart/report', 'multipart/related', 'multipart/alternative');
  	$arrSupportedDecodes = array('base64', 'quoted-printable');
		
		// Разбираем заголовки
		$arrLines = preg_split("/\n/", preg_replace("/\n\t/" , ' ', preg_replace("/\n  /" , ' ', $metas)));
		$arrData = array();
		
		foreach ($arrLines as $key => $line) {
			$posColon = strpos($line, ':');
			if ($posColon === false) continue;
			$arrData[substr($line, 0, $posColon)] = trim(substr($line, $posColon + 1));
		}
		if (isset($arrData['Content-Type'])) {
			$arrContentTypeInfo = explode(';', $arrData['Content-Type']);
			foreach ($arrContentTypeInfo as $contentInfo) {
				switch (trim($contentInfo)) {
					case 'text/plain': $arrData['type'] = 'text/plain'; break;
					case 'text/html': $arrData['type'] = 'text/html'; break;
					case 'multipart/mixed': $arrData['type'] = 'multipart/mixed'; break;
					case 'multipart/report': $arrData['type'] = 'multipart/report'; break;
					case 'multipart/related': $arrData['type'] = 'multipart/related'; break;
					case 'multipart/alternative': $arrData['type'] = 'multipart/alternative'; break;
					case 'charset=koi8-r': case 'charset=KOI8-R': $arrData['charset'] = 'KOI8-R'; break;
					default: 
						if (strpos($contentInfo, 'charset=') !== false) {
							$arrData['charset'] = trim(str_replace(array('charset=', '"'), '', $contentInfo));
						}
						if (strpos($contentInfo, 'boundary=') !== false) {
							$arrData['boundary'] = trim(str_replace(array('boundary=', '"'), '', $contentInfo));
						}
						break;
				}
			}
			if (isset($arrData['charset']) && $arrData['charset'] == '7 bit') unset($arrData['charset']);
			
			if (isset($arrData['type']) && ($arrData['type'] == 'text/plain' || $arrData['type'] == 'text/html')) { // Обработка единичного блока
			  
				
				if (!isset($arrData['Content-Transfer-Encoding']) || !in_array($arrData['Content-Transfer-Encoding'], $arrSupportedDecodes)) { // Если данные не закодированы
					if (isset($arrData['charset'])) $arrData['text'] = iconv($arrData['charset'], "UTF-8", $content);
			  	else $arrData['text'] = $content;	
			  }
			  else { // Если данные закодированы
			  	switch ($arrData['Content-Transfer-Encoding']) {
			  		case 'base64':
			  			$text = base64_decode($content);
			  			break;
			  		case 'quoted-printable':
			  			$text = quoted_printable_decode($content);
			  			break;
			  		default: $text = $content;
			  	}
			  	
			  	if (isset($arrData['charset'])) {
			  		$arrData['text'] = iconv($arrData['charset'], "UTF-8", $text);
			  	}
			  	else {
			  		$arrData['text'] = $text;
			  	}
			  }
			}
			elseif (isset($arrData['type']) && isset($arrData['boundary']) && (in_array($arrData['type'], $arrMultyparts))) { // Обработка мультиблока
				
				$contentOfBoundary = substr(
				  $content,
				  strpos($content, '--' . $arrData['boundary']) + strlen('--' . $arrData['boundary']),
				  strpos($content, '--' . $arrData['boundary'] . '--') - (strpos($content, '--' . $arrData['boundary']) + strlen('--' .$arrData['boundary'])) 
				);
				
				$arrContentBlocks = explode('--' . $arrData['boundary'], $contentOfBoundary);
  			foreach ($arrContentBlocks as $contentBlock) {
  				$arrData['text'][] = self::getMailInfoFromStr($contentBlock);
				}
			}
		}
		return $arrData;
  }

}
?>